#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>			//unistd.h 是 C 和 C++ 程序设计语言中提供对 POSIX 操作系统 API 的访问功能的头文件的名称
#include <sys/types.h> 		//基本系统数据类型,size_t，time_t，pid_t等
#include <sys/stat.h>		//获取文件属性
#include <fcntl.h>
#include <termios.h>
#include <errno.h>
#include <string.h>
#include <sys/mman.h>
#include "led_gpio_ctl.h"
#include "zlog.h"


int linux_gpio_config(char *pin, char *mode, char *value)
{
	int dev_fd, export_fd, dir_fd, ret;
	char dev_path[64], export_path[64], direct_path[64];
	char buf[10];

	sprintf(dev_path, "/sys/class/gpio/gpio%s/value", pin);
	sprintf(export_path, "/sys/class/gpio/export");
	sprintf(direct_path, "/sys/class/gpio/gpio%s/direction", pin);

	export_fd = open(export_path, O_WRONLY);
	if(export_fd == FAILURE) {
		perror("gpio export open failed!");
		dzlog_error("gpio export open failed!");
		return FAILURE;
	}

	write(export_fd, pin, strlen(pin));
	dev_fd = open(dev_path, O_RDWR);
	if(dev_fd == FAILURE) {
		perror("gpio dev open faield!");
		dzlog_error("gpio dev open faield!");
		return FAILURE;
	}

	dir_fd = open(direct_path, O_RDWR);
	if(dir_fd == FAILURE) {
		perror("gpio direct open failed!");
		dzlog_error("gpio direct open failed!");
		return FAILURE;
	}

	memset(buf, 0, sizeof(buf));
	strcpy(buf, mode);
	ret = write(dir_fd, buf, strlen(mode));
	if(ret == FAILURE) {
		perror("gpio direct write failed!");
		dzlog_error("gpio direct write failed!");
		close(export_fd);
		close(dir_fd);
		close(dev_fd);
		return FAILURE;
	}

	memset(buf, 0, sizeof(buf));
	strcpy(buf, value);
	ret = write(dev_fd, buf, strlen(value));
	if(ret == FAILURE) {
		perror("gpio write failed!");
		dzlog_error("gpio write failed!");
		close(export_fd);
		close(dir_fd);
		close(dev_fd);
		return FAILURE;
	}

	close(export_fd);
	close(dir_fd);
	close(dev_fd);

	return SUCCESS;
}



int led_daq_in_process(void)
{
	int dev_fd, ret;

	//linux_gpio_config("417", "out", "1");   

	dev_fd = open("/sys/class/gpio/gpio417/value", O_RDWR);
	if(dev_fd == FAILURE) {
		perror("daq led gpio 417 dev open faield!");
		dzlog_error("daq led gpio 417 dev open faield!");
		return FAILURE;
	}
	ret = write(dev_fd, "1", 1);
	if(ret == FAILURE) {
		perror("daq led gpio 417 dev write failed!");
		dzlog_error("daq led gpio 417 dev write failed!");
		close(dev_fd);
		return FAILURE;
	}

	close(dev_fd);

	return SUCCESS;
}


int led_daq_stop(void)
{
	int dev_fd, ret;

	//linux_gpio_config("417", "out", "0"); 

	dev_fd = open("/sys/class/gpio/gpio417/value", O_RDWR);
	if(dev_fd == FAILURE) {
		perror("daq led gpio 417 dev open faield!");
		dzlog_error("daq led gpio 417 dev open faield!");
		return FAILURE;
	}
	ret = write(dev_fd, "0", 1);
	if(ret == FAILURE) {
		perror("daq led gpio 417 dev write failed!");
		dzlog_error("daq led gpio 417 dev write failed!");
		close(dev_fd);
		return FAILURE;
	}

	close(dev_fd);

	return SUCCESS;
}


int afe_xc7a_reset_on(void)
{
	int dev_fd, ret;

	//linux_gpio_config("418", "out", "1");   

	dev_fd = open("/sys/class/gpio/gpio418/value", O_RDWR);
	if(dev_fd == FAILURE) {
		perror("xc7a_reset gpio 418 dev open faield!");
		dzlog_error("xc7a_reset gpio 418 dev open faield!");
		return FAILURE;
	}
	ret = write(dev_fd, "1", 1);
	if(ret == FAILURE) {
		perror("xc7a_reset gpio 418 dev write failed!");
		dzlog_error("xc7a_reset gpio 418 dev write failed!");
		close(dev_fd);
		return FAILURE;
	}

	close(dev_fd);

	return SUCCESS;
}


int afe_xc7a_reset_off(void)
{
	int dev_fd, ret;

	//linux_gpio_config("418", "out", "0"); 

	dev_fd = open("/sys/class/gpio/gpio418/value", O_RDWR);
	if(dev_fd == FAILURE) {
		perror("xc7a_reset gpio 418 dev open faield!");
		dzlog_error("xc7a_reset gpio 418 dev open faield!");
		return FAILURE;
	}
	ret = write(dev_fd, "0", 1);
	if(ret == FAILURE) {
		perror("xc7a_reset gpio 418 dev write failed!");
		dzlog_error("xc7a_reset gpio 418 dev write failed!");
		close(dev_fd);
		return FAILURE;
	}

	close(dev_fd);

	return SUCCESS;
}


void afe_xc7a_gpio_reset(void)
{
	usleep(100);
	afe_xc7a_reset_on();
	usleep(100);
	afe_xc7a_reset_off();
	usleep(100);
}


void gpio_default_init(sys_cfg_info *sys)
{
	linux_gpio_config("416", "out", "0");	//EMIO GPIO0 338 + 78 + 0  re485 de pin
	linux_gpio_config("417", "out", "0");	//EMIO GPIO0 338 + 78 + 1  daq led
	linux_gpio_config("418", "out", "0");	//EMIO GPIO0 338 + 78 + 2  afe1 reset
	afe_xc7a_gpio_reset();
	
	if (sys->debug == ON)
		printf("led and gpio417 init finished\n");
}



